using System;
using Gtk;
using System.IO;
using Pango;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Timers;
using System.Collections;

namespace monoServer
{
	public class GameClient
	{
		private DataManager dm;
		private CommunicatorParallel c;
		private Thread t;
		private Cron cron;
		
		private LoginWindow lw;
		private MainWindow mw;
		private DateTime lastPingResponse;
		private Configuration conf;
		private BugTable testtable;
		
		public GameClient()
		{
			this.conf = new Configuration(Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "/.monoclient/.config");
			this.conf.values["logdir"] = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "/" + (string)this.conf.values["logdir"];
			this.conf.values["logdirt"] = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "/" + (string)this.conf.values["logdirt"];
			this.dm = new DataManager();
			this.c = new CommunicatorParallel(new TcpClient((string)this.conf.values["server_ip"],int.Parse((string)this.conf.values["server_port"])), this.dm, new Logger(this.conf));
			this.t = new Thread(this.worker);
			this.lw = new LoginWindow(this.c);
			this.mw = new MainWindow();
			
			this.cron = new Cron();
			this.cron.addJob("sendping", new ElapsedEventHandler(this.c.sendPing),int.Parse((string)this.conf.values["send_ping_time"]));
			this.cron.addJob("checkpingresponse", new ElapsedEventHandler(this.checkPingResponse), int.Parse((string)this.conf.values["check_ping_response"]));
			this.cron.addJob("dumptesttable", new ElapsedEventHandler(this.dumptable), 30);
			this.cron.startAllJobs();
			this.lastPingResponse = DateTime.Now;

			this.testtable = new BugTable("testtable", true);
			this.testtable.addColumn("col1", typeof(string));
			this.testtable.addColumn("col2", typeof(string));
			this.testtable.addColumn("col3", typeof(string));
			
			TableConnector tc = new TableConnector(this.c, this.dm.currentConnectorKey);
			tc.table = this.testtable;
			//this.testtable.connector = tc;
			//this.c.connector = tc;
		}
		
		public void dumptable(object sender, ElapsedEventArgs e)
		{
			Console.WriteLine(this.testtable.toString());
		}
		
		public static void Main ()
		{
			Application.Init();
			GameClient gc = new GameClient();
			gc.start();
			Application.Run();
		}
		
		public void sendLogin(System.Object sender, EventArgs args)
		{
			this.lw.disable();
			/*
			Telegram tmp = new Telegram("LOGIN", Telegram.REQUEST, this.dm.currentTelegramKey);
			tmp.addParameter(this.lw.entry_username.Text);
			tmp.addParameter(DataManager.getMD5(this.lw.entry_password.Text));
			*/
			Telegram t = Telegram.getRequest(this.dm.currentTelegramKey, "LOGIN", this.lw.entry_username.Text, DataManager.getMD5(this.lw.entry_password.Text));
			this.c.sendTelegram(t);
		}
		
		public void checkPingResponse(object sender, ElapsedEventArgs e)
		{
			// TODO Wenn lastpingresponse länger her ist als n minuten muss der user ausgeloggt werden
		}
		
		public void start()
		{
			this.lw.button_login.Clicked += this.sendLogin;
			this.lw.show();
			this.t.Start();
		}
		
		public void worker()
		{
			while(true)
			{
				if(this.c.responseQueue.Count > 0)
				{
					Telegram t_res = (Telegram)this.c.responseQueue.Dequeue();
					ArrayList row = this.c.sendTelegrams.selectRow("id", t_res.requestKey);
					Telegram t_req = Telegram.Parse((string)row[4]);
					this.c.sendTelegrams.deleteRow("id", t_req.key);
					
					switch(t_req.keyWord)
					{
					case "LOGIN":
						if(t_res[0].Equals("OK"))
						{
							// Login erfolgreich
							this.lw.hide();
							this.mw.show();
						} else {
							string error_msg = t_res[1];
							this.lw.enable();
							this.lw.entry_errormsg.Text = error_msg;
						}
						break;
						
					case "PING":
						this.lastPingResponse = DateTime.Now;
						break;
						
					}
				}
				
				if(this.c.requestQueue.Count > 0)
				{
					Telegram t = (Telegram)this.c.requestQueue.Dequeue();
					
					switch(t.keyWord)
					{
					case "TERM":
						this.c.sendLogout();
						this.mw.hide();
						this.lw.show();
						break;
						
					case "LOGOUT":
						this.mw.hide();
						this.lw.enable();
						this.lw.show();
						break;
					}
				}
				
				if(this.c.connectorQueue.Count > 0)
				{
					Telegram t = (Telegram)this.c.connectorQueue.Dequeue();
					switch(t.keyWord)
					{
					case "BUGTABLE":
						string tableid = t[0];
						
						break;
					}
				}
			}
		}
	}
}

